package utils

import (
	"blog_api/conf"
	"crypto/md5"
	"crypto/sha1"
	"encoding/hex"
	"errors"
	"fmt"
	"gopkg.in/gomail.v2"
	"io"
	"math"
	"math/rand"
	"net"
	"sort"
	"strings"
	"time"
)

/**
 * GetRandomString
 * @Description: 生成一个随机字符串
 * @Author: Jazk-Z
 * @param l  字符串长度
 * @return string
 */
func GetRandomString(l int) string {
	str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	b := []byte(str)
	result := []byte{}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < l; i++ {
		result = append(result, b[r.Intn(len(b))])
	}
	return string(result)
}

/**
 * MakeSignature
 * @Description: 生成签名
 * @Author: Jazk-Z
 * @param timestamp
 * @param nonce
 * @return string
 */
func MakeSignature(timestamp, nonce string) string {
	// 1. 将 plat_token、timestamp、nonce三个参数进行字典序排序
	sl := []string{conf.TOKEN_KEY, timestamp, nonce}
	sort.Strings(sl)
	// 2. 将三个参数字符串拼接成一个字符串进行sha1加密
	s := sha1.New()
	io.WriteString(s, strings.Join(sl, ""))
	return fmt.Sprintf("%x", s.Sum(nil))
}

/**
 * Md5Encrypt
 * @Description: md5加密
 * @Author: Jazk-Z
 * @param str
 * @return string
 */
func Md5Encrypt(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

/**
 * DoubleStrMerge
 * @Description: 两个字符串交叉拼接，如’qwe‘和’asdfg‘，交叉后是：aqswdefg
 * @Author: Jazk-Z
 * @param str1
 * @param str2
 * @return string
 */
func DoubleStrMerge(str1, str2 string) string {
	slen1 := len(str1)
	slen2 := len(str2)
	if slen1 == 0 || slen2 == 0 {
		return ""
	}

	pwd_len := 0
	if slen1 >= slen2 {
		pwd_len = slen1
	} else {
		pwd_len = slen2
	}
	var newstr string
	for i := 0; i < pwd_len; i++ {
		if i < slen1 {
			child1 := str1[i : i+1]
			newstr += child1
		}

		if i < slen2 {
			child2 := str2[i : i+1]
			newstr += child2
		}
	}
	return newstr
}

/**
 * Ip2Long
 * @Description: ip地址转为int64整型数
 * @Author: Jazk-Z
 * @param ip
 * @return int64
 */
func Ip2Long(ip string) (uint64, error) {
	b := net.ParseIP(ip).To4()
	if b == nil {
		return 0, errors.New("invalid ipv4 format")
	}

	return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24, nil
}

/**
 * Long2Ip
 * @Description:int64整型数转为ip地址
 * @Author: Jazk-Z
 * @param ip
 * @return string
 */
func Long2Ip(i uint64) (string, error) {
	if i > math.MaxUint32 {
		return "", errors.New("beyond the scope of ipv4")
	}

	ip := make(net.IP, net.IPv4len)
	ip[0] = byte(i >> 24)
	ip[1] = byte(i >> 16)
	ip[2] = byte(i >> 8)
	ip[3] = byte(i)

	return ip.String(), nil
}

/**
 * SendMail
 * @Description: 发送邮件
 * @Author: Jazk-Z
 * @param mailTo
 * @param subject
 * @param body
 * @return error
 */
func SendMail(mailTo []string, subject string, body string) error {
	// 设置邮箱主体
	mailConn := map[string]string{
		"user": "zlztns@sina.com",  // 发送人邮箱（邮箱以自己的为准）
		"pass": "4ca3835fb4952fe9", // 发送人邮箱的密码，现在可能会需要邮箱 开启授权密码后在pass填写授权码
		"host": "smtp.sina.com",    // 邮箱服务器
	}

	m := gomail.NewMessage(
		// 发送文本时设置编码，防止乱码。 如果txt文本设置了之后还是乱码，那可以将原txt文本在保存时
		// 就选择utf-8格式保存
		gomail.SetEncoding(gomail.Base64),
	)
	m.SetHeader("From", m.FormatAddress(mailConn["user"], "博客访问报警")) // 添加别名
	m.SetHeader("To", mailTo...)                                     // 发送给用户(可以多个)
	m.SetHeader("Subject", subject)                                  // 设置邮件主题
	m.SetBody("text/html", body)                                     // 设置邮件正文

	/*
	   创建SMTP客户端，连接到远程的邮件服务器，需要指定服务器地址、端口号、用户名、密码，如果端口号为465的话，
	   自动开启SSL，这个时候需要指定TLSConfig
	*/
	d := gomail.NewDialer(mailConn["host"], 587, mailConn["user"], mailConn["pass"]) // 设置邮件正文
	// d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
	err := d.DialAndSend(m)
	return err
}
